package com.tlgen.rpc.utils;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.utils.StringUtils;
import com.tlgen.rpc.annotation.Fetch;
import okhttp3.*;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;

import static com.tlgen.rpc.utils.LoadBalanceUtils.loadBalanceServer;
import static com.tlgen.rpc.utils.MappingUtils.*;

public class OkHttpUtils {

    public static final String HTTP = "http://";

    public static String doGet(String path, Method method, String param) {
        OkHttpClient client = createOkHttpClient();
        String url = getCompleteRequestUrl(path, method);
        if (url == null) return null;
        if (!param.isEmpty()) {
            url = url + "?" + param;
        }
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();
        Response response;
        String result;
        try {
            response = client.newCall(request).execute();
            assert response.body() != null;
            result = response.body().string();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    @Nullable
    private static String getCompleteRequestUrl(String path, Method method) {
        Fetch annotation = method.getDeclaringClass().getAnnotation(Fetch.class);
        String serviceName = annotation.name(); // 服务名, 必填的属性
        String pattern = annotation.pattern(); // 匹配规则
        String url = annotation.url(); // 自定义的请求地址, 如 http://localhost:8088
        // 判断请求路径匹配规则, 如 path: /order-info 与 pattern: /order, 那么 path 可以匹配到
        if (StringUtils.isNotBlank(pattern) && !pattern.contains(path))
            return null;
        return HTTP + loadBalanceServer(serviceName, url) + path;
    }

    public static String doByForm(String path, Method method, Map<String, String> map) {
        OkHttpClient client = createOkHttpClient();
        // 构建一个 formBody builder
        FormBody.Builder builder = new FormBody.Builder();
        //循环 form 表单, 将表单内容添加到 form builder 中
        for (Map.Entry<String, String> entry : map.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            builder.add(key, value);
        }
        // 构建 formBody, 将其传入 Request 请求中
        FormBody body = builder.build();
        String url = getCompleteRequestUrl(path, method);
        if (url == null) return null;
        Call call = client.newCall(Objects.requireNonNull(createRequest(method, url, body)));
        // 返回请求结果
        try (Response response = call.execute()) {
            assert response.body() != null;
            return response.body().string();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String doByJson(String path, Method method, Object o) {
        OkHttpClient client = createOkHttpClient();
        RequestBody body = RequestBody.create(
                MediaType.parse("application/json; charset=utf-8"), JSONObject.toJSONString(o));
        String url = getCompleteRequestUrl(path, method);
        if (url == null) return null;
        Call call = client.newCall(Objects.requireNonNull(createRequest(method, url, body)));
        // 返回请求结果
        try {
            Response response = call.execute();
            assert response.body() != null;
            return response.body().string();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
